import java.awt.Color;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.TreeMap;

import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTextField;

import net.lbjhs.game2d.GameCanvas;
import net.lbjhs.game2d.KeyHandler;
import net.lbjhs.game2d.MouseHandler;
import net.lbjhs.game2d.ScreenSurfaceMetric;

public class TheWorld extends GameCanvas {

	int timer, id;

	ClientMap worldMap;

	boolean logged = false;

	ClientEntity user;

	ScreenSurfaceMetric sm;

	KeyHandler keys;

	ClientMessageSender cs;

	MouseHandler mouse = new MouseHandler();

	ScreenSurfaceMetric screen = getMetric();

	SynchQueue sq;

	JLabel health = new JLabel();

	Image ninja, pirate, yellowFish, redFish, blueFish, sword, axe, spear,
			ninjaAttack, pirateAttack, yellowFishAttack, redFishAttack,
			blueFishAttack, aoe;

	JTextField login = new JTextField("Username");

	JButton loginButton = new JButton("Login");

	public TheWorld(SynchQueue sq, ClientMessageSender cs1) {
		try {
			this.sq = sq;
			this.cs = cs1;
			ninja = ImageIO.read(new File("ninjaTile.png"));
			pirate = ImageIO.read(new File("pirateTile.png"));
			redFish = ImageIO.read(new File("redFishTile.png"));
			yellowFish = ImageIO.read(new File("yellowFishTile.png"));
			blueFish = ImageIO.read(new File("blueFishTile.png"));
			sword = ImageIO.read(new File("sword.png"));
			spear = ImageIO.read(new File("spear.png"));
			axe = ImageIO.read(new File("axe.png"));
			ninjaAttack = ImageIO.read(new File("ninjaTileAttack.png"));
			pirateAttack = ImageIO.read(new File("pirateTileAttack.png"));
			redFishAttack = ImageIO.read(new File("redFishTileAttack.png"));
			yellowFishAttack = ImageIO
					.read(new File("yellowFishTileAttack.png"));
			blueFishAttack = ImageIO.read(new File("blueFishTileAttack.png"));
			aoe = ImageIO.read(new File("fireballAttack.png"));
		} catch (IOException e) {
			System.out.println(e);
		}
		worldMap = new ClientMap();
		sm = getMetric();
		setBackground(Color.lightGray);
		addMouseListener(mouse);
		add(login);
		add(loginButton);
		login.setBounds(200, 200, 200, 30);
		loginButton.setBounds(250, 250, 100, 30);
		loginButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String s = login.getText();
				setBackground(new Color(75, 225, 75));
				cs.playerLogin(-1, s);
				remove(login);
				remove(loginButton);
				health.setText("Health: ");
				health.setBounds(3, 22, 60, 30);
				add(health);
			}
		});
//		sq.enqueue(new ServerPlayerSuccessfulLoginUpdate(1,
//				new PlayerEntityData(1, 1, "jimbob", new Point(0, 0), null)));
//
//		ServerPlayerInitialUpdate chau1 = new ServerPlayerInitialUpdate(2, 1,
//				1, 1, true);
//		ServerPlayerInitialUpdate chau2 = new ServerPlayerInitialUpdate(3, 2,
//				2, 1, true);
//		ServerPlayerInitialUpdate chau3 = new ServerPlayerInitialUpdate(4, 3,
//				3, 1, true);
//		ServerPlayerPositionUpdate chau4 = new ServerPlayerPositionUpdate(2, 3,
//				2);
//		ServerPlayerPositionUpdate chau5 = new ServerPlayerPositionUpdate(1, 2,
//				3);
//		sq.enqueue(chau1);
//		sq.enqueue(chau2);
//		sq.enqueue(chau3);
//		sq.enqueue(chau4);
//		sq.enqueue(chau5);
	}

	public void place(ClientEntity e) {
		worldMap.add(e);
		e.setPos(e.data.location.getX() * 50, e.data.location.getY() * 50);
		add(e);
	}

	public ClientEntity remove(Point p) {
		remove(worldMap.get(p));
		return worldMap.remove(p);
	}

	public void update(int time) {
		if (logged) {
			int x = (int) (user.data.location.getX());
			int y = (int) (user.data.location.getY());
			// code for receiving synchqueue
			String s = keys.getKeysTyped();
			if (s.contains("w")) {
				cs.playerMove(id, x, y + 1);
			}
			if (s.contains("a")) {
				cs.playerMove(id, x + 1, y);

			}
			if (s.contains("s")) {
				cs.playerMove(id, x, y - 1);
			}
			if (s.contains("d")) {
				cs.playerMove(id, x - 1, y);

			}
			if (s.contains("j")) {
				switch (user.data.direction) {
				case 1:
					cs.playerAbility(id, 1, x, y - 1);
					break;
				case 2:
					cs.playerAbility(id, 1, x + 1, y);
					break;
				case 3:
					cs.playerAbility(id, 1, x, y + 1);
					break;
				case 4:
					cs.playerAbility(id, 1, x - 1, y);
					break;
				}
			}
			if (s.contains("k")) {
				cs.playerAbility(id, 2, x, y);
			}
			if (s.contains("z")) {
				cs.playerAbility(id, 3, x, y);
			}
			if (s.contains("x")) {
				cs.playerAbility(id, 4, x, y);
			}
			ClientSetIterator i = (ClientSetIterator) worldMap
					.ClientEntitySetIterator();
			while (i.hasNext()) {
				ClientEntity e = (ClientEntity) i.next();
				if (e.duration != 9999) {
					if (e.expired == true) {
						remove(e);
					} else {
						e.duration -= time;
						if (e.duration <= 0) {
							e.expired = true;
						}
					}
				}
			}
		}
		while (!sq.isEmpty()) {
			if (user != null) {
				health.setText("Health: " + user.data.hp);
			}
			int x1;
			int y1;
			Object o = sq.dequeue();

			if (o instanceof ServerPlayerSuccessfulLoginUpdate) {
				ServerPlayerSuccessfulLoginUpdate p = (ServerPlayerSuccessfulLoginUpdate) o;
				user = new ClientEntity(p.d, pirate, 9999);
				place(user);
				// sm.setUserPosition(user.data.location.getX(),
				// user.data.location.getY());
				logged = true;
			}
			if (logged) {
				if (o instanceof ServerPlayerInitialUpdate) {
					ServerPlayerInitialUpdate p = (ServerPlayerInitialUpdate) o;
					ClientEntity CE = new ClientEntity(new PlayerEntityData(
							p.id, p.type, "bob", new Point(p.x, p.y), null),
							pirate, 9999);
					CE.data.location = new Point(p.x, p.y);
					if (p.player) {
						if (p.type == 0) {
							CE.i = pirate;
						} else {
							CE.i = ninja;
						}
					} else {
						CE.i = redFish;
					}
					place(CE);
				}
				if (o instanceof ServerPlayerExistenceUpdate) {
					ServerPlayerExistenceUpdate m = (ServerPlayerExistenceUpdate) o;

					if (m.exists() == true) {
						if (worldMap.get(m.id) == null) {

							place(new ClientEntity(new PlayerEntityData(m.id,
									2, "bob", new Point(0, 0), null), ninja,
									9999));

						}
					}

					if (m.exists() == false) {
						ClientEntity e1 = worldMap.remove(m.id);
						remove(m.id);
						if (m.id == user.data.id) {
							cs.playerLogoff(user.data.id, user.data.name);

						}
					}
				}

				if (o instanceof ServerPlayerHealthUpdate) {
					ServerPlayerHealthUpdate argasdsad = (ServerPlayerHealthUpdate) o;
					if (argasdsad.id == user.data.id) {
						user.data.hp = argasdsad.getHealth();
					}

				}

				if (o instanceof ServerPlayerInventoryUpdate) {
					ServerPlayerInventoryUpdate moomba2 = (ServerPlayerInventoryUpdate) o;
					user.data.hat = moomba2.getHat();
					user.data.weapon = moomba2.getWeapon();
					user.data.accessory = moomba2.getAccessory();

					// code for updating images
				}

				if (o instanceof ServerMonsterHealthUpdate) {
					ServerMonsterHealthUpdate m = (ServerMonsterHealthUpdate) o;
					ClientEntity e = worldMap.remove(m.id);
					EntityData moomba3 = (EntityData) e.data;
					moomba3.hp = m.getHealth();

				}

				if (o instanceof ServerPlayerPositionUpdate) {
					ServerPlayerPositionUpdate moomba4 = (ServerPlayerPositionUpdate) o;
					x1 = moomba4.getX();
					y1 = moomba4.getY();
					ClientEntity player = worldMap.get(moomba4.id);
					PlayerEntityData d = (PlayerEntityData) player.data;
					d.location = new Point(x1, y1);
					place(player);
					if (moomba4.getId() == d.id) {
						// sm.setUserPosition(x1 * 50, y1*50);
					}
				}
				if (o instanceof ServerMonsterMovementUpdate) {
					ServerMonsterMovementUpdate m = (ServerMonsterMovementUpdate) o;
					ClientEntity e = worldMap.remove(m.id);
					PlayerEntityData moomba = e.data;
					e.setPos(-625 + m.x * 50, -625 + m.y * 50);
					moomba.location = new Point(m.x, m.y);
					place(e);
				}
				if (o instanceof ServerMonsterAttackMessage) {
					ServerMonsterAttackMessage fachoom = (ServerMonsterAttackMessage) o;
					ClientEntity e = worldMap.get(fachoom.id);
					PlayerEntityData fachoomba = e.data;
					e = new ClientEntity(fachoomba, redFishAttack, 500);
					e.setPos(fachoomba.location);
					add(e);
				}
				if (o instanceof ServerPlayerAbilityMessage) {
					ServerPlayerAbilityMessage moomba9 = (ServerPlayerAbilityMessage) o;
					if (moomba9.getType() == 1) { // attack
						ClientEntity e = worldMap.get(moomba9.id);
						PlayerEntityData moombab = e.data;
						e = new ClientEntity(moombab, ninjaAttack, 250);
						e.setPos(-625 + moombab.location.getX() * 50, -625
								+ moombab.location.getY() * 50);
						add(e);
					} else if (moomba9.getType() == 2) { // AoE attack
						ClientEntity e = worldMap.get(moomba9.id);
						PlayerEntityData moombab = e.data;
						e = new ClientEntity(moombab, aoe, 250);
						e.setPos(-625 + moombab.location.getX() * 50, -625
								+ moombab.location.getY() * 50);
						add(e);
					}
					// else if (moomba9.getType() == 3){ //health potion?
					// }
					// else if (moomba9.getType() == 4){ //mana potion?
					// }
				}
			}
		}
	}
}
